/*
 * Copyright 2009 Gal Dolber
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.user.dragdrop.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.StyleInjector;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.dragdrop.client.resources.BlackBox;
import com.google.gwt.user.dragdrop.client.resources.Blue;
import com.google.gwt.user.dragdrop.client.resources.Common;

/**
 * Abstract controller
 */
public abstract class AbstractDragController implements MouseDownHandler,
		MouseMoveHandler, MouseUpHandler {

	static {
		Common common = GWT.create(Common.class);
		BlackBox black = GWT.create(BlackBox.class);
		Blue blue = GWT.create(Blue.class);
		StyleInjector.inject(common.common().getText());
		StyleInjector.inject(black.blackTheme().getText());
		StyleInjector.inject(blue.blueTheme().getText());
	}
	
	// Mouse events
	MouseEvent<?> currentMouseEvent;

	// Mouse position
	protected int mousex;
	protected int mousey;

	// onStart mouse position
	protected int initialx;
	protected int initialy;

	// Mouse button
	protected int button;

	// Is mouse down?
	protected boolean isMouseDown = false;

	/**
	 * Mouse button
	 */
	public int getButton() {
		return button;
	}

	/**
	 * @return The current event
	 */
	public MouseEvent<?> getCurrentEvent() {
		return currentMouseEvent;
	}

	protected Element getCurrentEventTarget() {
		return currentMouseEvent.getNativeEvent().getEventTarget().cast();
	}

	/**
	 * Get the delta x
	 */
	public int getDeltaX() {
		return getMouseX() - getInitialX();
	}

	/**
	 * Get the delta y
	 */
	public int getDeltaY() {
		return getMouseY() - getInitialY();
	}

	public Element getEventTarget() {
		return currentMouseEvent.getNativeEvent().getEventTarget().cast();
	}

	/**
	 * Relative mouse x from the widget
	 */
	public int getInitialX() {
		return initialx;
	}

	/**
	 * Relative mouse y from the widget
	 */
	public int getInitialY() {
		return initialy;
	}

	/**
	 * Mouse x
	 */
	public int getMouseX() {
		return mousex;
	}

	/**
	 * Mouse y
	 */
	public int getMouseY() {
		return mousey;
	}

	/**
	 * @return isMouseDown
	 */
	public boolean isMouseDown() {
		return isMouseDown;
	}

	@Override
	public void onMouseDown(MouseDownEvent event) {
		// Save the event
		currentMouseEvent = event;

		// Save mouse position
		initialx = mousex = event.getClientX();
		initialy = mousey = event.getClientY();

		// Set mouse down
		isMouseDown = true;

		// Get button
		button = event.getNativeButton();
	}

	@Override
	public void onMouseMove(MouseMoveEvent event) {
		// Save the event
		currentMouseEvent = event;

		// Save mouse position
		mousex = event.getClientX();
		mousey = event.getClientY();
	}

	@Override
	public void onMouseUp(MouseUpEvent event) {
		// Save event
		currentMouseEvent = event;

		// Save mouse position
		mousex = event.getClientX();
		mousey = event.getClientY();

		// Set mouse down
		isMouseDown = false;
	}

	public void stopEventPropagation() {
		currentMouseEvent.preventDefault();
		currentMouseEvent.stopPropagation();
	}
}
